package com.yz.forlogin.security.utils;

import com.yz.forlogin.security.constants.SecurityConstants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 钰杰
 */
public class JwtTokenUtils {


    /**
     * 生成足够的安全随机密钥，以适合符合规范的签名
     */
    private static byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SecurityConstants.JWT_SECRET_KEY);

    private static SecretKey secretKey = Keys.hmacShaKeyFor(apiKeySecretBytes);

    public static String createToken(String username, List<String> roles, boolean isRememberMe) {
        long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;

        String tokenPrefix = Jwts.builder()
                .setHeaderParam("typ", SecurityConstants.TOKEN_TYPE)
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles))
                .setIssuer("SnailClimb")
                .setIssuedAt(new Date())
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
        return SecurityConstants.TOKEN_PREFIX + tokenPrefix;
    }

    public static boolean isTokenExpired(String token) {
        Date expiredDate = getTokenBody(token).getExpiration();
        return expiredDate.before(new Date());
    }

    public static void flushToken(String token) {
        String usernameByToken = getUsernameByToken(token);
        List<SimpleGrantedAuthority> userRolesByToken = getUserRolesByToken(token);
        ArrayList<String> roles = new ArrayList<>();
        for (SimpleGrantedAuthority role : userRolesByToken) {
            roles.add(role.toString());
        }
        //不设置rememberme
        createToken(usernameByToken, roles, false);
    }

    public static String getUsernameByToken(String token) {
        return getTokenBody(token).getSubject();
    }

    /**
     * 获取用户所有角色
     */
    public static List<SimpleGrantedAuthority> getUserRolesByToken(String token) {
        String role = (String) getTokenBody(token)
                .get(SecurityConstants.ROLE_CLAIMS);
        return Arrays.stream(role.split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    }

    private static Claims getTokenBody(String token) {
        String substring = token.substring(7);
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(substring)
                .getBody();
    }


    public static void main(String[] args) {
        String tokenss = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2wiOiJST0xFX0FETUlOIiwiaXNzIjoiU25haWxDbGltYiIsImlhdCI6MTU3NjA0NDkwNywic3ViIjoi5bCP5bCP5by6IiwiZXhwIjoxNTc2MDQ4NTA3fQ.4OpYdJgTDG-zN4mzW0zbZaOdijbGmjDHgvM-oDZgIzQ";
//        List<SimpleGrantedAuthority> userRolesByToken = getUserRolesByToken(tokenss);
//        boolean tokenExpired = isTokenExpired("Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2wiOiJST0xFX0FETUlOIiwiaXNzIjoiU25haWxDbGltYiIsImlhdCI6MTU3NjA0NDkwNywic3ViIjoi5bCP5bCP5by6IiwiZXhwIjoxNTc2MDQ4NTA3fQ.4OpYdJgTDG-zN4mzW0zbZaOdijbGmjDHgvM-oDZgIzQ");
        flushToken(tokenss);


    }

}